﻿
#include <ctime>
#include <iostream>
#include <array>
#include <vector>
#include <map>
#include <functional>
#include <string>
#include <string_view>
#include <sstream>
#include <charconv>
#include <format>

// 计算单线程函数执行时间的方法
class ScopedTimer {
public:
    ScopedTimer(const char *name)
            : m_name(name),
              m_beg(std::chrono::steady_clock::now()) {}

    ~ScopedTimer() {
        auto end = std::chrono::steady_clock::now();
        auto dur = std::chrono::duration_cast<std::chrono::nanoseconds>(end - m_beg);
        std::cout << m_name << " : " << dur.count() << " ns\n";
    }

private:
    const char *m_name;
    std::chrono::time_point<std::chrono::high_resolution_clock> m_beg;
};

// 方案一：宏定义
#define _ToStr(x) #x
#define ToStr(x) _ToStr(x)

// 方案二：
namespace detail {
    template<uint8_t... digits>
    struct positive_to_chars {
        static const char value[];
        static constexpr size_t size = sizeof...(digits);
    };
    template<uint8_t... digits> const char positive_to_chars<digits...>::value[] = {('0' + digits)..., 0};

    template<uint8_t... digits>
    struct negative_to_chars {
        static const char value[];
    };
    template<uint8_t... digits> const char negative_to_chars<digits...>::value[] = {'-', ('0' + digits)..., 0};

    template<bool neg, uint8_t... digits>
    struct to_chars : positive_to_chars<digits...> {
    };

    template<uint8_t... digits>
    struct to_chars<true, digits...> : negative_to_chars<digits...> {
    };

    template<bool neg, uintmax_t rem, uint8_t... digits>
    struct explode : explode<neg, rem / 10, rem % 10, digits...> {
    };

    template<bool neg, uint8_t... digits>
    struct explode<neg, 0, digits...> : to_chars<neg, digits...> {
    };

    template<typename T>
    constexpr uintmax_t cabs(T num) { return (num < 0) ? -num : num; }
}

template<typename T, T num>
struct string_from : ::detail::explode<num < 0, ::detail::cabs(num)> {
};

//string_from<unsigned, 1>::value; //"1"
//static_assert(string_from<unsigned, 1>::size == 1);

int main(int argc, char const *argv[]) {
    // 编译期间计算
    std::cout << ToStr(100) << std::endl;

    std::cout << string_from<unsigned, 10>::value << std::endl;
    static_assert(string_from<unsigned, 10>::size == 2);

    // 运行期计算

    // 在c++17中应该优先使用std::to_chars来获得最优的性能。
    // 在c++17之前可以使用sprintf和std::to_string
    // 尽量不要用std::stringstream
    std::cout << std::to_string(200) << std::endl;
    {
        std::stringstream ss;
        ss << 201;
        std::cout << ss.str() << std::endl;
    }
    {
        std::cout << std::format("{}", 202) << std::endl;
    }
    {
        char str[10] = {'\0'};
        sprintf(str, "%d", 203);
        std::cout << str << std::endl;
    }
    {
        char str[10] = {'\0'};
        std::to_chars(str, str + 10, 0xCCA4);
        std::cout << str << std::endl;

        std::to_chars(str + strlen(str), str + 10, 0xCCA4, 16);
        std::cout << str << std::endl;
    }

    return 0;
}
